import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { Icon } from 'antd';
import keyboard from 'keyboard-key';
import classnames from 'classnames';
import Node from '@design/core/components/Node';
import Value from '@design/core/model/value';
import { findNode, getKey } from '@design/core/utils/find-node';
import { getElement } from '@design/core/utils/dom';
import { DropDecorator, ResizeDecorator } from '@design/desktop/decorator';
import { getNode, setDataTransfer } from '../../utils/serialize';
import './index.less';

@DropDecorator()
@ResizeDecorator()
class Designer extends PureComponent {
  static propTypes = {
    value: PropTypes.instanceOf(Value).isRequired,
    editor: PropTypes.object.isRequired,
  };

  componentDidMount() {
    document.addEventListener('mousemove', this.handleMouseMove);
    document.addEventListener("keydown", this.handleKeyDown);
  }

  componentWillUnmount() {
    document.addEventListener('mousemove', this.handleMouseMove);
    document.addEventListener("keydown", this.handleKeyDown);
  }

  handleMouseMove = event => {
    this.mouseX = event.pageX;
    this.mouseY = event.pageY;
  };

  handleCut = event => {
    const { value, editor } = this.props;
    const selectedNode = value.selection.first();
    if (selectedNode) {
      event.preventDefault();
      editor.removeNode(selectedNode.key);
      setDataTransfer(event.clipboardData, selectedNode);
    }
  };

  handleCopy = event => {
    const { value } = this.props;
    const selectedNode = value.selection.first();
    if (selectedNode) {
      event.preventDefault();
      setDataTransfer(event.clipboardData, selectedNode);
    }
  };

  handlePaste = event => {
    event.stopPropagation();
    event.preventDefault();
    const node = getNode(event.clipboardData);
    if (node) {
      const {
        value: { document },
        editor,
      } = this.props;
      const element = getElement(document.key);
      const rect = element.getBoundingClientRect();
      const newNode = node.clone();
      const position = { x: this.mouseX - rect.x, y: this.mouseY - rect.y };
      editor.insertNodeByKey(newNode, document.key, document.nodes.size);
      editor.updateNode(newNode, { position });
    }
  };

  handleKeyDown = event => {
    // const { value, editor } = this.props;
    // const selectedNode = value.selection.first();
    const code = keyboard.getCode(event);
    // const addY = delta => {
    //   if (!selectedNode) {
    //     return;
    //   }
    //   const y = parseInt(selectedNode.position.y, 10);
    //   const position = selectedNode.position.set('y', y + delta);
    //   editor.updateNode(selectedNode, { position });
    // };
    // const addX = delta => {
    //   if (!selectedNode) {
    //     return;
    //   }
    //   const x = parseInt(selectedNode.position.x, 10);
    //   const position = selectedNode.position.set('x', x + delta);
    //   editor.updateNode(selectedNode, { position });
    // };
    switch (code) {
      // case keyboard.ArrowUp:
      //   addY(-10);
      //   break;
      // case keyboard.ArrowDown:
      //   addY(10);
      //   break;
      // case keyboard.ArrowLeft:
      //   addX(-10);
      //   break;
      // case keyboard.ArrowRight:
      //   addX(10);
      //   break;
      // case keyboard.Delete:
      // case keyboard.Backspace:
      //   if (selectedNode) {
      //     editor.removeNode(selectedNode.key);
      //   }
      //   break;
      // case keyboard.Z:
      //   if (event.ctrlKey) {
      //     editor.undo();
      //   }
      //   break;
      default:
        break;
    }
  };

  handleClick = event => {
    const { value, editor } = this.props;
    const selectedNode = value.selection.first();
    if (selectedNode && selectedNode.key === getKey(event.target)) {
      return;
    }
    let node = findNode(event.target, value);
    if (node) {
      // window.localStorage.setItem("NODE", JSON.stringify(node));
      node = editor.getNotAtomicNode(node);      
      editor.closePropertyEditor();
      editor.setSelection([node]);
    } else {
      editor.setSelection([]);
    }
  };

  renderNode = node => {
    const { value } = this.props;
    const { selection } = value;
    const isSelected = value.isSelected(node);
    let selectedPath;
    if (selection.first()) {
      selectedPath = node.getPath(selection.first().key);
    }
    return (
      <Node
        selectedPath={selectedPath}
        isSelected={isSelected}
        key={node.key}
        node={node}
        parent={this.props.value.document}
        editor={this.props.editor}
        value={value}
      />
    );
  };

  onEdit = () => {
    const { editor, node } = this.props;
    if (editor.showPropertyEditor) {
      editor.showPropertyEditor(node);
    }
  };

  renderInlineToolbar = () => {
    return (
      <div className="inline-toolbar">
        <Icon type="edit" onClick={this.onEdit} />
      </div>
    );
  };

  render() {
    const { value, connectDropTarget } = this.props;
    const { document } = value;
    const children = document.nodes.toArray().map(this.renderNode);
    const attributes = { 'data-key': document.key };
    const isSelected = value.isSelected(document);
    const classNames = classnames('document', { selected: isSelected });// 最外层面板
    const { renderResizer, rect } = this.props;
    const style = document.style.toJS();
    style.height = rect.height || style.height;
    return connectDropTarget(
      <div
        {...attributes}
        style={style}
        className={classNames}
        onClickCapture={this.handleClick}
        onKeyDown={this.handleKeyDown}
        onCopy={this.handleCopy}
        onCut={this.handleCut}
        onPaste={this.handlePaste}
        // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
        tabIndex={0}
      >
        {children}
        {isSelected && this.renderInlineToolbar()}
        {isSelected && renderResizer(['bottom'])}
        {this.props.children}
      </div>
    );
  }
}

export default Designer;
